#pragma once

#include "vcclr.h"
#include "WTypes.h"
#include "NxCoreAPI.h"
#include "NxCoreConnector.h"
#include "NxCoreCache.h"

using namespace System;
using namespace System::Data::Common;
using namespace System::IO;
using namespace System::Reflection;

namespace Tradex {
	namespace Connectivity {
		namespace NxCore {

			private enum ThreadStatus { Starting, Running, Stopping, Stopped };

			ref class NxCoreConnector;

			public class NativeConnector {

				public:

				[System::Security::SecurityCritical()]
				NativeConnector (NxCoreConnector^ pManagedConnector);

				[System::Security::SecurityCritical()]
				~NativeConnector ();

				[System::Security::SecurityCritical()]
				void Connect (char* pTape);

				[System::Security::SecurityCritical()]
				void Disconnect ();

				private:

				[System::Security::SecurityCritical()]
				static DWORD NxCoreThread (LPVOID lParam);
				volatile ThreadStatus NxCoreThreadStatus;
				static int __stdcall NxCoreCallback(const NxCoreSystem* pNxCoreSys,const NxCoreMessage* pNxCoreMsg);
				int __stdcall OnNxCoreCallback(const NxCoreSystem* pNxCoreSys,const NxCoreMessage* pNxCoreMsg);

				void ProcessNxCoreInitialized ();

				int ProcessNxCoreStatus (const NxCoreSystem* pNxCoreSys);
				int ProcessNxCoreExgQuote (const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMsg);
				int ProcessNxCoreMmQuote (const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMsg);
				int ProcessNxCoreTrade (const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMsg);

				int ProcessNxCoreCategory (const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMsg);
				int ProcessNxCoreSymbolChange (const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMsg);
				int ProcessNxCoreSymbolSpin (const NxCoreSystem* pNxCoreSys, const NxCoreMessage* pNxCoreMsg);

				private:
				gcroot<NxCoreConnector^> pManaged;
				gcroot<NxCoreCache^> pCache;

				char* _Tape;

				HMODULE hLib;
				NxCoreProcessTape pfNxProcessTape;
				NxCorePriceToDouble pfNxPriceToDouble;
				NxCoreGetDefinedString pfNxCoreGetDefinedString;
				NxCoreGetSymbolAtom32 pfNxGetSymbolAtom32;

			};

		}
	}
}

